home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / src / source / smbmnt.c.z / smbmnt.c
Encoding:
C/C++ Source or Header  |  1998-10-28  |  7.2 KB  |  296 lines

  1. /*
  2.  *  smbmount.c
  3.  *
  4.  *  Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <signal.h>
  11. #include <pwd.h>
  12. #include <grp.h>
  13. #include <sys/socket.h>
  14. #include <sys/param.h>
  15. #include <netinet/in.h>
  16. #include <netdb.h>
  17. #include <sys/stat.h>
  18. #include <sys/types.h>
  19. /* #include <sys/wait.h> */  /* generates a warning here */
  20. extern pid_t waitpid(pid_t, int *, int);
  21. #include <sys/errno.h>
  22. #include <unistd.h>
  23. #include <fcntl.h>
  24. #include <errno.h>
  25. #include <ctype.h>
  26. #include <stdlib.h>
  27. #include <sys/mount.h>
  28. #include <mntent.h>
  29.  
  30. #include <linux/fs.h>
  31. #include <linux/smb.h>
  32. #include <linux/smb_mount.h>
  33.  
  34. #include <asm/unistd.h>
  35.  
  36. static char *progname;
  37.  
  38.  
  39. static void
  40. usage(void)
  41. {
  42.         printf("usage: %s mount-point [options]\n", progname);
  43.         printf("Try `%s -h' for more information\n", progname);
  44. }
  45.  
  46. static void
  47. help(void)
  48. {
  49.         printf("\n");
  50.         printf("usage: %s mount-point [options]\n", progname);
  51.         printf("-u uid         uid the mounted files get\n"
  52.                "-g gid         gid the mounted files get\n"
  53.                "-f mode        permission the files get (octal notation)\n"
  54.                "-d mode        permission the dirs get (octal notation)\n"
  55.            "-P pid         connection handler's pid\n\n"
  56.            "-s share       share name on server\n\n"
  57.                "-h             print this help text\n");
  58. }
  59.  
  60. static int
  61. parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
  62. {
  63.         int opt;
  64.         struct passwd *pwd;
  65.         struct group  *grp;
  66.  
  67.         while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
  68.     {
  69.                 switch (opt)
  70.         {
  71.                 case 'u':
  72.                         if (isdigit(optarg[0]))
  73.             {
  74.                                 data->uid = atoi(optarg);
  75.                         }
  76.             else
  77.             {
  78.                                 pwd = getpwnam(optarg);
  79.                                 if (pwd == NULL)
  80.                 {
  81.                                         fprintf(stderr, "Unknown user: %s\n",
  82.                                                 optarg);
  83.                                         return 1;
  84.                                 }
  85.                                 data->uid = pwd->pw_uid;
  86.                         }
  87.                         break;
  88.                 case 'g':
  89.                         if (isdigit(optarg[0]))
  90.             {
  91.                                 data->gid = atoi(optarg);
  92.                         }
  93.             else
  94.             {
  95.                                 grp = getgrnam(optarg);
  96.                                 if (grp == NULL)
  97.                 {
  98.                                         fprintf(stderr, "Unknown group: %s\n",
  99.                                                 optarg);
  100.                                         return 1;
  101.                                 }
  102.                                 data->gid = grp->gr_gid;
  103.                         }
  104.                         break;
  105.                 case 'f':
  106.                         data->file_mode = strtol(optarg, NULL, 8);
  107.                         break;
  108.                 case 'd':
  109.                         data->dir_mode = strtol(optarg, NULL, 8);
  110.                         break;
  111.                 case 's':
  112.                         *share = optarg;
  113.                         break;
  114.                 default:
  115.                         return -1;
  116.                 }
  117.         }
  118.         return 0;
  119.         
  120. }
  121.  
  122. static char *
  123. fullpath(const char *p)
  124. {
  125.         char path[MAXPATHLEN];
  126.  
  127.     if (strlen(p) > MAXPATHLEN-1)
  128.     {
  129.         return NULL;
  130.     }
  131.  
  132.         if (realpath(p, path) == NULL)
  133.     {
  134.                 return strdup(p);
  135.     }
  136.     return strdup(path);
  137. }
  138.  
  139. /* Check whether user is allowed to mount on the specified mount point */
  140. static int
  141. mount_ok(struct stat *st)
  142. {
  143.         if (!S_ISDIR(st->st_mode))
  144.         {
  145.                 errno = ENOTDIR;
  146.                 return -1;
  147.         }
  148.     
  149.         if (   (getuid() != 0)
  150.             && (   (getuid() != st->st_uid)
  151.                 || ((st->st_mode & S_IRWXU) != S_IRWXU)))
  152.         {
  153.                 errno = EPERM;
  154.                 return -1;
  155.         }
  156.  
  157.         return 0;
  158. }
  159.  
  160. int 
  161. main(int argc, char *argv[])
  162. {
  163.     char *mount_point, *share_name = NULL;
  164.     FILE *mtab;
  165.     int fd, um;
  166.     unsigned int flags;
  167.     struct smb_mount_data data;
  168.     struct stat st;
  169.     struct mntent ment;
  170.  
  171.         progname = argv[0];
  172.  
  173.     memset(&data, 0, sizeof(struct smb_mount_data));
  174.  
  175.     if (   (argc == 2)
  176.            && (argv[1][0] == '-')
  177.            && (argv[1][1] == 'h')
  178.            && (argv[1][2] == '\0'))
  179.     {
  180.         help();
  181.         return 0;
  182.     }
  183.  
  184.         if (geteuid() != 0) {
  185.                 fprintf(stderr, "%s must be installed suid root\n", progname);
  186.                 exit(1);
  187.         }
  188.  
  189.     if (argc < 2)
  190.     {
  191.         usage();
  192.         return 1;
  193.     }
  194.  
  195.         mount_point = argv[1];
  196.  
  197.         argv += 1;
  198.         argc -= 1;
  199.  
  200.         if (stat(mount_point, &st) == -1) {
  201.                 fprintf(stderr, "could not find mount point %s: %s\n",
  202.                         mount_point, strerror(errno));
  203.                 exit(1);
  204.         }
  205.  
  206.         if (mount_ok(&st) != 0) {
  207.                 fprintf(stderr, "cannot mount on %s: %s\n",
  208.                         mount_point, strerror(errno));
  209.                 exit(1);
  210.         }
  211.  
  212.     data.version = SMB_MOUNT_VERSION;
  213.  
  214.         /* getuid() gives us the real uid, who may umount the fs */
  215.         data.mounted_uid = getuid();
  216.  
  217.         data.uid = getuid();
  218.         data.gid = getgid();
  219.         um = umask(0);
  220.         umask(um);
  221.         data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
  222.         data.dir_mode  = 0;
  223.  
  224.         if (parse_args(argc, argv, &data, &share_name) != 0) {
  225.                 usage();
  226.                 return -1;
  227.         }
  228.  
  229.         if (data.dir_mode == 0) {
  230.                 data.dir_mode = data.file_mode;
  231.                 if ((data.dir_mode & S_IRUSR) != 0)
  232.                         data.dir_mode |= S_IXUSR;
  233.                 if ((data.dir_mode & S_IRGRP) != 0)
  234.                         data.dir_mode |= S_IXGRP;
  235.                 if ((data.dir_mode & S_IROTH) != 0)
  236.                         data.dir_mode |= S_IXOTH;
  237.         }
  238.  
  239.     flags = MS_MGC_VAL;
  240.  
  241.     if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
  242.     {
  243.         perror("mount error");
  244.         printf("Please refer to the smbmnt(8) manual page\n");
  245.         return -1;
  246.     }
  247.  
  248.         ment.mnt_fsname = share_name ? share_name : "none";
  249.         ment.mnt_dir = fullpath(mount_point);
  250.         ment.mnt_type = "smbfs";
  251.         ment.mnt_opts = "";
  252.         ment.mnt_freq = 0;
  253.         ment.mnt_passno= 0;
  254.  
  255.         mount_point = ment.mnt_dir;
  256.  
  257.     if (mount_point == NULL)
  258.     {
  259.         fprintf(stderr, "Mount point too long\n");
  260.         return -1;
  261.     }
  262.     
  263.         if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
  264.         {
  265.                 fprintf(stderr, "Can't get "MOUNTED"~ lock file");
  266.                 return 1;
  267.         }
  268.         close(fd);
  269.     
  270.         if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
  271.         {
  272.                 fprintf(stderr, "Can't open " MOUNTED);
  273.                 return 1;
  274.         }
  275.  
  276.         if (addmntent(mtab, &ment) == 1)
  277.         {
  278.                 fprintf(stderr, "Can't write mount entry");
  279.                 return 1;
  280.         }
  281.         if (fchmod(fileno(mtab), 0644) == -1)
  282.         {
  283.                 fprintf(stderr, "Can't set perms on "MOUNTED);
  284.                 return 1;
  285.         }
  286.         endmntent(mtab);
  287.  
  288.         if (unlink(MOUNTED"~") == -1)
  289.         {
  290.                 fprintf(stderr, "Can't remove "MOUNTED"~");
  291.                 return 1;
  292.         }
  293.  
  294.     return 0;
  295. }    
  296.